home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / oper_sys / presto / prest_04.lha / src / swtch.s < prev    next >
Text File  |  1989-08-08  |  5KB  |  212 lines

  1. /*
  2.  * Switch routines
  3.  *
  4.  *    save all registers
  5.  *    disable interrupts
  6.  *    remember current sp and fp
  7.  *    restore old sp and fp
  8.  *    enable interrupts
  9.  *    restore old registers on return
  10.  */
  11.  
  12. /*
  13.  *    Context Switch
  14.  *
  15.  *    This routine must be atomic (nonpreemptable).
  16.  *    This file contains the code for three different hardware
  17.  *    systems.  They should be broken out into separate files,
  18.  *    but hey...
  19.  */
  20.  
  21. #ifdef    ns32000
  22.     .file    "swtch.s"
  23.     .text
  24.     .align    2
  25.     .globl    __Thread_swtch
  26. __Thread_swtch:
  27.     # _au0_this is in 8(fp)
  28.     # save r0 through r7
  29.     # must save even scratch registers since we may have been
  30.     # preempted.
  31.     enter    [r0,r1,r2,r3,r4,r5,r6,r7],0    
  32.     #
  33.     #    WARNING: The following offsets depend on the setup of class
  34.     #         Thread and all those from which it is derived
  35.     #
  36.     #
  37.     movqd    0, _interrupts_enabled;
  38.  
  39.     movd    20(8(fp)), r0    # r0 = this->t_csp
  40.     movd    24(8(fp)), r1    # r1 = this->t_fp
  41.     sprd    sp, 20(8(fp))    # this->t_csp = sp
  42.     sprd    fp, 24(8(fp))    # this->t_fp = fp
  43.     lprd    sp, r0        # sp = (old)this->t_csp
  44.     lprd       fp, r1        # fp = (old)this->t_fp
  45.     
  46.     movqd    1, _interrupts_enabled;
  47.     #
  48.     # restore regs
  49.     #
  50.     exit    [r0,r1,r2,r3,r4,r5,r6,r7]
  51.     ret    0
  52. #endif
  53.  
  54. #ifdef    i386
  55.     .file    "swtch.s"
  56.     .text
  57.     .align    2
  58.     .globl    __Thread_swtch
  59. __Thread_swtch:
  60.     #
  61.     # _au0_this is in 4(%esp) at entry.
  62.     # No need to save scratch registers since preemption code does that.
  63.     #
  64.     pushl    %ebp
  65.     movl    %esp, %ebp
  66.     pushl    %edi
  67.     pushl    %esi
  68.     pushl    %ebx
  69.     #
  70.     #    WARNING: The following offsets depend on the setup of class
  71.     #         Thread and all those from which it is derived
  72.     #
  73.     movl    $0, _interrupts_enabled;
  74.  
  75.     movl    8(%ebp), %eax        # eax == "this"
  76.     xchgl    %esp, 20(%eax)        # swap stack-pointer with thread
  77.     xchgl    %ebp, 24(%eax)        # swap frame-pointer with thread
  78.  
  79.     movb    $1, _interrupts_enabled;
  80.     #
  81.     # restore regs
  82.     #
  83.     popl    %ebx
  84.     popl    %esi
  85.     popl    %edi
  86.     leave
  87.     ret
  88.  
  89. /*
  90.  * init_stack(Thread* newthread, int* new_stack_top)
  91.  *    Push a proper "swtch" register context, so next swtch() in
  92.  *    newthread restores registers correctly and returns to caller's caller.
  93.  *    Save apprioriate stack and frame pointer in thread.
  94.  *
  95.  * Called in Thread::runrun().
  96.  *
  97.  * Assumes caller has no register variables, thus current contents are
  98.  * appropriate for caller's caller.
  99.  */    
  100.     .text
  101.     .align    2
  102.     .globl    _init_stack
  103. _init_stack:
  104.     popl    %ecx        # ecx = return address
  105.     popl    %eax        # eax -> thread
  106.     popl    %edx        # edx = new stack top
  107.     pushl    %edi        # push registers ...
  108.     pushl    %esi        #    ... ala swtch()
  109.     pushl    %ebx        #        ... entry.
  110.     movl    %esp, 20(%eax)    # save callers stack pointer in thread
  111.     movl    %ebp, 24(%eax)    # save callers frame pointer in thread
  112.     leal    -8(%edx), %esp    # on new stack, room for caller to pop args
  113.     jmp    *%ecx        # return
  114. #endif
  115.  
  116. /*
  117.  * The vax version of swtch assumes that "this" points to a thread whose
  118.  * t_proc field points to the process object corresponding to the context in
  119.  * which swtch is executing.  Thus "this->t_proc->p_interruptible" controls
  120.  * preemption of the process executing swtch.
  121.  */
  122.  
  123. #ifdef vax
  124.     .file    "swtch.s"
  125. .text
  126.     .data
  127.     .text
  128.     .align    2
  129.     .globl    __Thread_swtch
  130.  
  131. __Thread_swtch:
  132.     .word 0xfff        # entry mask (save regs r0-r11)
  133.     movl    4(ap), r2    # r2 = this
  134.     movl    28(r2), r3    # r3 = this->t_proc
  135.     movl    $0, 20(r3)    # this->t_proc->p_interruptible = 0
  136.  
  137.     movl    24(r2), r1    # r1 = this->t_fp
  138.     movl    fp, 24(r2)    # this->t_fp = fp
  139.     movl       r1, fp        # fp = (old)this->t_fp
  140.  
  141.     movl    $1, 20(r3)    # this->t_proc->p_interruptible = 1
  142.     ret
  143. #endif vax
  144.  
  145.  
  146. #ifdef mc68020
  147. |
  148. | _Thread_swtch and init_stack routines for the mc68020 -- Jim Carson 1/2/89
  149. |
  150.     .data 
  151.     .lcomm _swtch_tmp, 4
  152.     .even
  153.     .text
  154.     .even
  155.     .globl  __Thread_swtch
  156. __Thread_swtch:
  157.     link a6, #0
  158.         movl    a3, sp@-
  159.         movl    a4, sp@-
  160.         movl    a5, sp@-
  161.  
  162. #ifdef THREAD_HAS_INTERRUPTIBLE_FIELD
  163.     movl a6@(8), a0               | this
  164.     movl a0@(28), a0           |      ->proc
  165.     clrl a0@(20)                     |            ->p_interruptible = 0
  166. #else
  167.     clrl _interrupts_enabled
  168. #endif
  169.  
  170.         movl    a6@(8), a0                 | a0 == "this"
  171.  
  172.         movl    a0@(20), _swtch_tmp        | _swtch_tmp = this->t_csp
  173.         movl    sp, a0@(20)                | this->t_csp = sp
  174.         movl    _swtch_tmp, sp             | sp = _swtch_tmp
  175.                        |
  176.         movl    a0@(24), _swtch_tmp        | _swtch_tmp = this->t_fp
  177.         movl    a6, a0@(24)                | this->t_fp  = fp
  178.         movl    _swtch_tmp, a6             | fp = _swtch_tmp
  179.  
  180. #ifdef THREAD_HAS_INTERRUPTIBLE_FIELD
  181.     movl a0@(28), a0           | this->proc
  182.     movl #1, a0@(20)                     |            ->p_interruptible = 1
  183. #else
  184.     movl #1, _interrupts_enabled
  185. #endif
  186.  
  187.         movl    sp@+, a5
  188.         movl    sp@+, a4
  189.         movl    sp@+, a3
  190.     unlk a6
  191.         rts
  192.         .globl  f68881_used
  193.  
  194. |
  195. | init_stack(Thread* newthread, int* new_stack_top)
  196. |
  197.         .text
  198.         .align  2
  199. .globl  _init_stack
  200. _init_stack:
  201.         movl    sp@+, a0        | a0 = return address
  202.         movl    sp@+, a1        | a1 = thread       
  203.         movl    sp@+, a2        | a2 = new stack top 
  204.         movl    a3, sp@-        | push registers ...  
  205.         movl    a4, sp@-        |      ... ala swtch() 
  206.         movl    a5, sp@-        |              ... entry.  
  207.         movl    sp, a1@(20)     | Save caller's stack ptr in thread
  208.         movl    a6, a1@(24)     | Save caller's frame ptr in thread
  209.         lea     a2@(-8), sp     | On new stack, room for caller to pop args
  210.         jmp     a0@        | Return
  211. #endif mc68020
  212.